package crawler.model;

import business.service.MongoDbFactory;
import com.mongodb.BasicDBObject;
import com.mongodb.DB;
import com.mongodb.DBCollection;
import com.mongodb.DBCursor;
import com.mongodb.DBObject;
import crawler.common.PatternData;
import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
import org.apache.log4j.Logger;
import org.bson.types.ObjectId;

public class DatabaseModel {

    private static final String DATABASE_COLLECTION = "database";
    private static final Logger logger = Logger.getLogger(DatabaseModel.class);
    private static final Lock createLock_ = new ReentrantLock();
    private static DatabaseModel _instance = null;

    public static DatabaseModel getInstance() {
        if (_instance == null) {
            createLock_.lock();
            try {
                if (_instance == null) {
                    _instance = new DatabaseModel();

                }
            } finally {
                createLock_.unlock();
            }
        }
        return _instance;
    }

    public DatabaseModel() {
        try {
        } catch (Exception ex) {
            logger.error("PatternModel: " + ex);
        }
    }

    public List<PatternData> getList(int start, int limit) {
        List<PatternData> lstPattern = new LinkedList<>();
        try {
            BasicDBObject basicDBObject = new BasicDBObject("created", -1);
            DB db = MongoDbFactory.getConnection();
            DBCollection coll = db.getCollection(DATABASE_COLLECTION);
            DBCursor cursor = coll.find().sort(basicDBObject);

            if (limit != -1) {
                cursor = cursor.skip(start).limit(limit);
            }

            while (cursor.hasNext()) {
                DBObject dbObject = cursor.next();
                lstPattern.add(fromDB(dbObject));
            }
        } catch (Exception ex) {
            logger.error("PatternModel.getListPattern: " + ex.getMessage(), ex);
        }
        return lstPattern;
    }

    public PatternData getById(String id) {
        try {
            BasicDBObject basicDBObject = new BasicDBObject("_id", new ObjectId(id));
            DB db = MongoDbFactory.getConnection();
            DBCollection coll = db.getCollection(DATABASE_COLLECTION);
            DBCursor cursor = coll.find(basicDBObject);
            if (cursor.hasNext()) {
                DBObject dbObject = cursor.next();
                PatternData patternData = fromDB(dbObject);
                return patternData;
            }
        } catch (Exception ex) {
            logger.error("PatternModel.getById: " + ex.getMessage(), ex);
        }
        return null;
    }
    public static PatternData fromDB(DBObject dbObject){
        String objectId = ((ObjectId) dbObject.get("_id")).toString();
        String name = (String) dbObject.get("name");
        String link = (String) dbObject.get("link");
        String category = (String) dbObject.get("category");
        String title = (String) dbObject.get("title");
        String thumb = (String) dbObject.get("thumb");
        String desc = (String) dbObject.get("desc");
        String content = (String) dbObject.get("content");
        String tags = (String) dbObject.get("tags");
        String journalist = (String) dbObject.get("journalist");
        String published = (String) dbObject.get("published");
        long created = (long) dbObject.get("created");
        String author = (String) dbObject.get("author");
        long updated = 0;//(long) dbObject.get("updated");
        String editor = "";//(String) dbObject.get("editor");
        PatternData patternData =
                new PatternData(objectId, name, link, title, category,
                        thumb, desc, content, tags, journalist,
                        published, author, created, editor, updated);
        return patternData;
    }
    public long countList() {
        long count = 0;
        try {
            DB db = MongoDbFactory.getConnection();
            DBCollection coll = db.getCollection(DATABASE_COLLECTION);
            count = coll.getCount();
        } catch (Exception ex) {
            logger.error("PatternModel.countList: " + ex.getMessage(), ex);
        }
        return count;
    }

    public boolean delete(String id) {
        try {
            DB db = MongoDbFactory.getConnection();
            DBCollection coll = db.getCollection(DATABASE_COLLECTION);
            coll.remove(new BasicDBObject("_id", new ObjectId(id)));

            return true;
        } catch (Exception ex) {
            logger.error("PatternModel.delete: " + ex.getMessage(), ex);
        }
        return false;
    }
    
    public String add(PatternData patternData) {
        String id = "";
        try {
            BasicDBObject basicDBObject = new BasicDBObject()
                    .append("name", patternData.getName())
                    .append("link", patternData.getLink())
                    .append("category", patternData.getCategory())
                    .append("title", patternData.getTitle())
                    .append("thumb", patternData.getThumb())
                    .append("desc", patternData.getDesc())
                    .append("content", patternData.getContent())
                    .append("journalist", patternData.getJournalist())
                    .append("tags", patternData.getTags())
                    .append("published", patternData.getPublished())
                    .append("author", patternData.getAuthor())
                    .append("created", patternData.getCreated())
                    .append("editor", patternData.getAuthor())
                    .append("updated", patternData.getCreated());
            
            DB db = MongoDbFactory.getConnection();
            DBCollection coll = db.getCollection(DATABASE_COLLECTION);
            coll.insert(basicDBObject);
            
            ObjectId objectId = (ObjectId)basicDBObject.get( "_id" );
            id = objectId.toString();
        } catch (Exception ex) {
            logger.error("PatternModel.add: " + ex.getMessage(), ex);
        }
        return id;
    }
    
    public boolean update(PatternData patternData) {
        try {
            BasicDBObject basicDBObject = new BasicDBObject()
                    .append("name", patternData.getName())
                    .append("link", patternData.getLink())
                    .append("category", patternData.getCategory())
                    .append("title", patternData.getTitle())
                    .append("thumb", patternData.getThumb())
                    .append("desc", patternData.getDesc())
                    .append("content", patternData.getContent())
                    .append("journalist", patternData.getJournalist())
                    .append("tags", patternData.getTags())
                    .append("published", patternData.getPublished())
                    .append("author", patternData.getAuthor())
                    .append("created", patternData.getCreated())
                    .append("editor", patternData.getAuthor())
                    .append("updated", patternData.getCreated());
            DB db = MongoDbFactory.getConnection();
            DBCollection coll = db.getCollection(DATABASE_COLLECTION);
            
            BasicDBObject updateDBObject = new BasicDBObject("$set", basicDBObject);
            BasicDBObject searchDBQuery = new BasicDBObject("_id", new ObjectId(patternData.getId()));
            coll.update(searchDBQuery, updateDBObject);
            return true;
        } catch (Exception ex) {
            logger.error("PatternModel.update: " + ex.getMessage());
        }
        return false;
    }

}
